#pragma once
#include <iostream>
#include <string>

#include <jsoncpp/json/json.h>
#include "httplib.h"
#include "database.hpp"
#include "session.hpp"
#include "room_player.hpp"

#include "grpc.grpc.pb.h"
#include <grpcpp/grpcpp.h>
#include <memory>
#include<algorithm>
#include <iostream>
 #include <strstream>
#include<unordered_map>




using namespace httplib;
using namespace std;

class WebGobang
{
    public:
        WebGobang()
        {
            db_svr_ = NULL;
            all_sess_ = NULL;
            pm_ = NULL;
            rm_ = NULL;

            match_pool_.clear();
            match_pool_num_ = 0;
            pthread_mutex_init(&vec_lock_, NULL);
            pthread_cond_init(&vec_cond_, NULL);
        }

        ~WebGobang()
        {
            if(db_svr_)
            {
                delete db_svr_;
                db_svr_ = NULL;
            }

            if(all_sess_)
            {
                delete all_sess_;
                all_sess_ = NULL;
            }

            if(pm_)
            {
                delete pm_;
                pm_ = NULL;
            }

            if(rm_)
            {
                delete rm_;
                rm_ = NULL;
            }

            pthread_mutex_destroy(&vec_lock_);
            pthread_cond_destroy(&vec_cond_);
        }

        /*
         * 初始化用户管理模块的类指针
         * 初始化数据库模块的类指针
         * ...
         * */
        int Init()
        {
            //初始化数据库
            db_svr_ = new DataBaseSvr();
            if(db_svr_ == NULL)
            {
                return -1;
            }

            if(db_svr_->Connect2Mysql() == false)
            {
                printf("conect to mysql failed\n");
                return -2;
            }
                       
            MYSQL_RES* res;
          
            string sql="select MAX(room_id) from  game_info ;";
            if(db_svr_->ExecuteSql(sql, &res)==false)
            {
                    mysql_free_result(res);
                    cout<<"执行失败"<<endl;
             }
            MYSQL_ROW row = mysql_fetch_row(res);
            int id=atoi(row[0]);
             
            std::cout<<row[0]<<std::endl;
           
             mysql_free_result(res);
             std::cout<<3<<std::endl;
            all_sess_ = new AllSessionInfo();
            if(all_sess_ == NULL)
            {
                cout<<"new ALLSessionInfo失败"<<endl;
                return -3;
            }

            pm_ = new PlayerManager();
            if(pm_ == NULL)
            {
                cout<<"new PlayerManager失败"<<endl;
                return -4;
            }

            rm_ = new RoomManager();
            if(rm_ == NULL)
            {
                cout<<"new RoomManager失败"<<endl;
                return -5;
            }
            rm_->prepare_id_=id+1;
            return 0;
        }
        
        static void* loop(void* arg)
        {
            pthread_detach(pthread_self());
            WebGobang* wg = (WebGobang*)arg;
            // 服务构建器，用于构建同步或者异步服务
            grpc::ServerBuilder builder;
            // 添加监听的地址和端口，后一个参数用于设置认证方式，这里选择不认证
            builder.AddListeningPort("0.0.0.0:33333",grpc::InsecureServerCredentials());
            // 创建服务对象
            ServiceImpl service;
            service.rm_=wg->rm_;
            // 注册服务
            builder.RegisterService(&service);
            // 构建服务器
            std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
                
            std::cout<<"Server Runing"<<std::endl;
            // 进入服务处理循环（必须在某处调用server->Shutdown()才会返回）
            server->Wait();
            return nullptr;

        } 
        // 继承自生成的Service类，实现三个虚函数
        class ServiceImpl:public Rpc::Server::Service {
            public:                                                                                                              
            grpc::Status QueryOpponent(grpc::ServerContext*  context,const Rpc::Request* request,Rpc::Reply* response) override
            {
            if(rm_->map_room_[atoi(request->room_id().c_str())].p1_==atoi(request->my_id().c_str()))
            response->set_oppid(to_string(rm_->map_room_[atoi(request->room_id().c_str())].p2_));
            else
            response->set_oppid(to_string(rm_->map_room_[atoi(request->room_id().c_str())].p1_));

            cout<<response->oppid()<<endl;//0 0x1462690 0x1462690
            cout<<request->room_id()<<":"<<endl;
            // grpc状态可以设置message,所以也可以用来返回一些信息
            return grpc::Status(grpc::StatusCode::OK,"hello");
            }
            RoomManager* rm_;
        };
        void StartWebGobang()
        {
            //注册账号
            http_svr_.Post("/register", [this](const Request& res, Response& resp){

                   Json::Reader r;//Json解释器，可以使用 parse() 方法将Json格式的字符串解析成Json::Value
                
                   Json::Value v;
                   r.parse(res.body, v);//解析
                   Json::Value resp_json;
                    int tmp=this->all_sess_->CheckSessionInfo(res);
                   resp_json["status"] = this->db_svr_->AddUser(v);
                 //可以将Json::Value转换为字符串。其中FastWriter结果是无格式的字符串。而StyleWriter是格式化的字符串
                   resp.body = this->Serializa(resp_json);
                    cout<<resp_json["status"]<<endl;
                   resp.set_header("Content-Type", "application/json");
                    });

            //登录
            http_svr_.Post("/login", [this](const Request& res, Response& resp){
                //body是e-mail和password
                    //1.校验用户提交的账号和密码(同数据库当中的数据进行校验)
                   Json::Reader r;
                   Json::Value v;
                   r.parse(res.body, v);
                   cout << res.body << endl;

                   int user_id = this->db_svr_->QueryUserExist(v);
                   cout<<user_id<<endl;
                   //2.组织http响应进行回复（json）
                   string tmp = "";
                   //生成会话
                   if(user_id > 0)
                   {
                       //登录成功 生成会话
                        Session sess(v, user_id);
                        string session_id = sess.GetSessionId();
                        //JSESSIONID=xxxxx
                        tmp = "JSESSIONID=" + session_id;
                        //插入session到管理的all_session
                        all_sess_->SetSessionInfo(session_id, sess);

                        //插入到player管理类
                        this->pm_->InsertPlayer2Map(user_id);
                   }

                   Json::Value resp_json;
                   resp_json["status"] = user_id <= 0 ? false:true;
                   resp.body = this->Serializa(resp_json);
              
                   resp.set_header("Set-Cookie", tmp.c_str());
                   resp.set_header("Content-Type", "application/json");
            });
            http_svr_.Post("/regretrcover", [this](const Request& res, Response& resp){
                    //1.会话校验
                  
                   Json::Reader r;
                   Json::Value v;
                   r.parse(res.body, v);
                   int user_id = this->db_svr_->QueryUserExist(v);
                    rm_->map_room_[v["room_id"].asInt()].popv(v["fg"].asString());
            
                   Json::Value resp_json;
                    resp_json["status"] = true;
                   resp.body = this->Serializa(resp_json);
                  
                   resp.set_header("Content-Type", "application/json");
                    });
            http_svr_.Get("/GetUserId", [this](const Request& res, Response& resp){
                    //1.会话校验
                   Json::Value resp_json;
                   resp_json["user_id"] = this->all_sess_->CheckSessionInfo(res);
                    
                   resp.body = this->Serializa(resp_json);
                   resp.set_header("Content-Type", "application/json");
                    });

            /*
             * 将当前这个用户放到匹配池当中
             * */
            http_svr_.Get("/SetMatch", [this](const Request& res, Response& resp){
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                                resp_json["status"] = -1;
                        }
                        else
                        {
                        //将当前的用户放到匹配池当中
                            resp_json["status"] = this->PushPlayer2MatchPool(user_id);
                        }

                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });

            http_svr_.Get("/Match", [this](const Request& res, Response& resp){
                        Json::Value resp_json;
                        //数据库user_id
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            //使用用户id， 判断是否该用户有房间号， 
                            //       如果有房间号， 则配成功
                            //       如果没有， 则匹配失败
                            
                            //1.获取当前这个用户， 
                            //       1.1 想要获取用户持有的棋子
                            //       1.2 想要获取用户所在的房间号
                            
                            Player r = this->pm_->GetPlayerInfo(user_id);
                            if(r.room_id_ >= 1000 && r.player_status_ == PLAYING)
                            {
                                //匹配成功
                                resp_json["status"] = 1;
                                resp_json["room_id"] = r.room_id_;
                                resp_json["chess_name"] = r.chess_name_;
                              
                                //分别查询
                            string sql="select name from sys_user where user_id="+to_string(rm_->map_room_[r.room_id_].p1_);
                            MYSQL_RES* res;
                            
                            if(db_svr_->ExecuteSql(sql, &res)==false)
                            {
                                mysql_free_result(res);
                                cout<<"执行失败"<<endl;
                                resp_json["status"] = -1;
                            }
                            MYSQL_ROW row = mysql_fetch_row(res);
                           
                            

                            string sql2="select name from sys_user where user_id="+to_string(rm_->map_room_[r.room_id_].p2_);
                            
                            if(db_svr_->ExecuteSql(sql2, &res)==false)
                            {
                                mysql_free_result(res);
                                cout<<"执行失败"<<endl;
                                resp_json["status"] = -1;
                            }
                            MYSQL_ROW row1 = mysql_fetch_row(res);
                            
                            if(r.user_id_==rm_->map_room_[r.room_id_].p1_)
                                {
                                    resp_json["myname"] =row[0];
                                    resp_json["youname"] = row1[0];
                                }
                            else
                                {
                                    resp_json["myname"] = row1[0];
                                    resp_json["youname"] = row[0];
                                    
                                }
                            
                                if(resp_json["myname"]==resp_json["youname"])
                                {
                                     resp_json["status"] = -2;
                                }
                            mysql_free_result(res);
                            }
                        }

                            
    
                        cout<<resp_json["myname"]<<" "<<resp_json["youname"]<<endl;
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });

            http_svr_.Post("/IsMyTurn", [this](const Request& res, Response& resp)
                    {
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            Json::Reader r;
                            Json::Value v;
                            r.parse(res.body, v);

                            int room_id = v["room_id"].asInt();
                            int user_id = v["user_id"].asInt();
                            resp_json["status"] = this->rm_->IsMyTurn(room_id, user_id);
                        }
                        
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });

            http_svr_.Post("/Step", [this](const Request& res, Response& resp)
                    {
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            resp_json["status"] = this->rm_->Step(res.body);
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });

            http_svr_.Post("/GetPeerStep", [this](const Request& res, Response& resp)
                    {
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            string peer_step;
                            int a=this->rm_->GetRoomStep(res.body, peer_step) ;
                            if(a< 0)
                            {
                                resp_json["status"] = a;
                            }
                            else
                            {
                                resp_json["status"] = 1;
                                resp_json["peer_step"] = peer_step;
                            }
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });
            // http_svr_.Post("/Regret",[this](const Request& res, Response& resp)
            //         {
            //             Json::Value resp_json;
            //             int user_id = this->all_sess_->CheckSessionInfo(res); 
            //             if(user_id <= 0)
            //             {
            //                 resp_json["status"] = -1;
            //             }
            //             else
            //             {
            //                 Json::Reader r;
            //                 Json::Value v;
            //                 r.parse(res.body, v);

            //                 int room_id = v["room_id"].asInt();
            //                 resp_json["status"] = this->rm_->Regret(room_id);
                              
            //             }
            //             resp.body = this->Serializa(resp_json);
            //             resp.set_header("Content-Type", "application/json");
            //         });
                    
            // http_svr_.Post("/IsRegret",[this](const Request& res, Response& resp)
            //         {
            //             Json::Value resp_json;
            //             int user_id = this->all_sess_->CheckSessionInfo(res); 
            //             if(user_id <= 0)
            //             {
            //                 resp_json["status"] = -1;
            //             }
            //             else
            //             {
            //                 Json::Reader r;
            //                 Json::Value v;
            //                 r.parse(res.body, v);

            //                 int room_id = v["room_id"].asInt();
            //                 resp_json["status"] = this->rm_->Regret(room_id);
                              
            //             }
            //             resp.body = this->Serializa(resp_json);
            //             resp.set_header("Content-Type", "application/json");
            //         });
            http_svr_.Post("/Winner", [this](const Request& res, Response& resp)
                    {
                      
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            Json::Reader r;
                            Json::Value v;
                            r.parse(res.body, v);

                            int room_id = v["room_id"].asInt();
                            int user_id = v["user_id"].asInt();

                            //1.设置对局的赢家到对应的房间
                            this->rm_->SetRoomWinner(room_id, user_id);
                            //2.将对局的步骤保存在数据库当中（持久化）
                                 //2.1 获取当前房间信息
                                 //2.2 将房间信息交给数据库模块继续持久化
                            resp_json["status"] = this->db_svr_->InsertRoomInfo(this->rm_->GetRoomInfo(room_id));
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });
            http_svr_.Post("/Next", [this](const Request& res, Response& resp)
                    {
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            Json::Reader r;
                            Json::Value v;
                            r.parse(res.body, v);
                        
                            int room_id = v["room_id"].asInt();
                            if(rm_->map_room_[room_id].recover_vec_.size()==0)
                            {
                                if(load(room_id)==false)
                                {
                                    cout<<"加载数据库失败"<<endl;
                                }

                            }
                             int ret= this->rm_->Next(room_id);
                             resp_json["status"]=ret;
                            if(ret!=-1)
                            {
                                resp_json["content"] = this->rm_->map_room_[room_id].recover_vec_[ret];
                            }
                            
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");

                    });
            http_svr_.Post("/Prev", [this](const Request& res, Response& resp)
                    {
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            Json::Reader r;
                            Json::Value v;
                            r.parse(res.body, v);
                           
                            int room_id = v["room_id"].asInt();
                            if(rm_->map_room_[room_id].recover_vec_.size()==0)
                            {
                                if(load(room_id)==false)
                                {
                                    cout<<"加载数据库失败"<<endl;
                                }
                            }
                            resp_json["status"]= this->rm_->Prev(room_id);
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });
                    //重置
            http_svr_.Post("/Remake", [this](const Request& res, Response& resp)
                    {
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            Json::Reader r;
                            Json::Value v;
                            r.parse(res.body, v);
                           
                            int room_id = v["room_id"].asInt();
                            rm_->map_room_[room_id].r_num=-1;
                           
                            resp_json["status"] = 1;
                              
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });
            http_svr_.Post("/ShowInit", [this](const Request& res, Response& resp)
                    {
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            Json::Reader r;
                            Json::Value v;
                            r.parse(res.body, v);
                           
                            int room_id = v["room_id"].asInt();
                            rm_->map_room_[room_id].r_num=-1;
                           
                            resp_json["status"] = 1;
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });
            http_svr_.Post("/showlist", [this](const Request& res, Response& resp)
                    {
                        int count=0;
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            Json::Reader r;
                            Json::Value v;
                            r.parse(res.body, v);
                            //查询查询p1为user_id
                            string sql="select * from game_info where p1_="+to_string(user_id)+"  group by room_id";
                             MYSQL_RES* res;
                           
                            if(db_svr_->ExecuteSql(sql, &res)==false)
                            {
                                mysql_free_result(res);
                                cout<<"执行失败"<<endl;
                                resp_json["status"] = -1;
                            }
                            int num_row = mysql_num_rows(res);
                            int num_col = mysql_num_fields(res);
                            int i,j;
                             MYSQL_RES* res1;
                            for(i = 0;i < num_row;i++)
                            {
                                
                                string tmp="";
                                MYSQL_ROW row = mysql_fetch_row(res);
                                vector<string> ret;
                                for(int j=0;j<4;j++)
                                {
                                     if(j==1||j==2)
                                    {
                                        //查询p1、p2的名字
                                        string sql2="select name from sys_user where user_id="+to_string(atoi(row[j]));
                                         if(db_svr_->ExecuteSql(sql2, &res1)==false)
                                            {
                                                mysql_free_result(res1);
                                                cout<<"执行失败"<<endl;
                                                resp_json["status"] = -1;
                                            }
                                           MYSQL_ROW row1 = mysql_fetch_row(res1);
                                            tmp=tmp+row1[0]+'!';
                                            ret.push_back(row1[0]);
                                    }
                                    else if(j==3)
                                    {
                                        //胜者名字
                                        tmp=tmp+(row[j]==row[j-1]?ret[1]:ret[0]);
                                        tmp+='!';
                                    }
                                    else
                                    {
                                           tmp=tmp+row[j]+'!';
                                    }
                                }
                                cout<<tmp<<endl;
                               resp_json[to_string(count++)] = tmp;
                            }
                            //查询p2
                            sql="select * from game_info where p2_="+to_string(user_id)+"  group by room_id";
                            
                            if(db_svr_->ExecuteSql(sql, &res)==false)
                            {
                                mysql_free_result(res);
                                cout<<"执行失败"<<endl;
                                resp_json["status"] = -1;
                            }
                             num_row = mysql_num_rows(res);
                             num_col = mysql_num_fields(res);
                            for(i = 0;i < num_row;i++)
                            {
                                string tmp="";
                                MYSQL_ROW row = mysql_fetch_row(res);
                                 vector<string> ret;
                                for(int j=0;j<4;j++)
                                {
                                     if(j==1||j==2)
                                    {
                                        string sql2="select name from sys_user where user_id="+to_string(atoi(row[j]));
                                         if(db_svr_->ExecuteSql(sql2, &res1)==false)
                                            {
                                                mysql_free_result(res1);
                                                cout<<"执行失败"<<endl;
                                                resp_json["status"] = -1;
                                            }
                                            
                                           MYSQL_ROW row1 = mysql_fetch_row(res1);
                                            tmp=tmp+row1[0]+'!';
                                            ret.push_back(row1[0]);

                                    }
                                    else if(j==3)
                                    {
                                        tmp=tmp+(row[j]==row[j-1]?ret[1]:ret[0]);
                                        tmp+='!';
                                    }
                                    else
                                    {
                                           tmp=tmp+row[j]+'!';
                                    }
                                }
                                cout<<tmp<<endl;
                               resp_json[to_string(count++)] = tmp;
                            }
                            //返回对局数量以及映射
                             resp_json["count"]=count;
                             resp_json["status"] = 1;
                            mysql_free_result(res);
                             mysql_free_result(res1);
                            
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");

                    });
            http_svr_.Get("/Searchinfo", [this](const Request& res, Response& resp)
                    {
                        Json::Value resp_json;
                        cout<<"test"<<endl;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            Json::Reader r;
                            Json::Value v;
                            r.parse(res.body, v);
                            MYSQL_RES* res;
                            string sql="select name from sys_user where user_id="+to_string(user_id);
                            if(db_svr_->ExecuteSql(sql, &res)==false)
                            {
                                mysql_free_result(res);
                                cout<<"执行失败"<<endl;
                                resp_json["status"] = -1;
                            }
                            MYSQL_ROW row = mysql_fetch_row(res);
                            resp_json["name"]=row[0];

                            sql="select * from game_info where p1_="+to_string(user_id)+"  group by room_id";
                            if(db_svr_->ExecuteSql(sql, &res)==false)
                            {
                                mysql_free_result(res);
                                cout<<"执行失败"<<endl;
                                resp_json["status"] = -1;
                            }
                            int num_row1 = mysql_num_rows(res);
                            sql="select * from game_info where p2_="+to_string(user_id)+"  group by room_id";
                            if(db_svr_->ExecuteSql(sql, &res)==false)
                            {
                                mysql_free_result(res);
                                cout<<"执行失败"<<endl;
                                resp_json["status"] = -1;
                            }
                            int num_row2 = mysql_num_rows(res);
                            cout<<"对局场数"<<num_row1+num_row2<<endl;
                             resp_json["playcount"] = num_row1+num_row2;


                            sql="select * from game_info where winner="+to_string(user_id)+"  group by room_id";
                           
                            if(db_svr_->ExecuteSql(sql, &res)==false)
                            {
                                mysql_free_result(res);
                                cout<<"执行失败"<<endl;
                                resp_json["status"] = -1;
                            }
                            int num_row3 = mysql_num_rows(res);
                            cout<<"赢的次数"<<num_row3<<endl;
                            resp_json["wincount"] = num_row3;
                            resp_json["status"] = 1;
                            mysql_free_result(res);
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");

                    });
            http_svr_.Post("/Restart", [this](const Request& res, Response& resp)
                    {
                        Json::Value resp_json;
                        int user_id = this->all_sess_->CheckSessionInfo(res); 
                        if(user_id <= 0)
                        {
                            resp_json["status"] = -1;
                        }
                        else
                        {
                            Json::Reader r;
                            Json::Value v;
                            r.parse(res.body, v);

                            int room_id = v["room_id"].asInt();
                            int user_id = v["user_id"].asInt();
                            //1.将用户信息进行重置， 用户状态， 游戏房间等信息
                            this->pm_->ResetUserGameInfo(user_id);
                            //2.将用户所在房间及进行移除
                            this->rm_->RemoveRoom(room_id);
                            //重新匹配
                            resp_json["status"] = 0;
                        }
                        resp.body = this->Serializa(resp_json);
                        resp.set_header("Content-Type", "application/json");
                    });

            pthread_t tid;
            int ret = pthread_create(&tid, NULL, MatchServer, (void*)this);
            if(ret < 0)
            {
                printf("create mathc thread faield\n");
                exit(1);
            }
            pthread_t tid1;
            ret = pthread_create(&tid1, NULL, loop,(void*) this);
            if(ret < 0)
            {
                printf("create mathc thread faield\n");
                exit(1);
            }
            http_svr_.set_mount_point("/", "./www");
            http_svr_.listen("0.0.0.0", 8082);
        }

        bool load(int room_id)
        {
             string sql="select *  from game_info where room_id="+to_string(room_id);
        
            MYSQL_RES* res;
            if(db_svr_->ExecuteSql(sql.c_str(), &res)==false)
            {
                mysql_free_result(res);
                cout<<"执行失败"<<endl;
                return false;
             }
            cout<<"tzc3"<<endl;
            int num_row = mysql_num_rows(res);
            int num_col = mysql_num_fields(res);
            int i,j;
                            
            for(i = 0;i < num_row;i++)
            {
                MYSQL_ROW row = mysql_fetch_row(res);
                rm_->map_room_[room_id].recover_vec_.push_back(row[num_col-1]);
             }
            // for(auto &x:rm_->map_room_[room_id].recover_vec_)
            //  {
            //     cout<<x<<endl;
            // }
            mysql_free_result(res);
            return true;
        }
        static void* MatchServer(void* arg)
        {
            pthread_detach(pthread_self());
            WebGobang* wg = (WebGobang*)arg;

            while(1)
            {
                pthread_mutex_lock(&wg->vec_lock_);
                while(wg->match_pool_num_ < 2)
                {
                    pthread_cond_wait(&wg->vec_cond_, &wg->vec_lock_);
                    printf("wait player come\n");
                }

                //匹配池当中的人数一定为大于等于2
                //  奇数： 一定由一个玩家要轮空
                //  偶数：两两进行匹配
                int last_id = -1;
                auto& vec = wg->match_pool_;
                size_t vec_size = vec.size();
                if(vec_size % 2)
                {
                    //当前人数是奇数
                    last_id = vec[vec_size - 1];
                    vec_size -= 1;
                }

                for(int i = vec_size - 1; i >= 0; i -= 2)
                {
                    int player_one = vec[i];
                    int player_two = vec[i - 1];

                    //假设匹配成功
                    int room_id = wg->rm_->CreateRoom(player_one, player_two);

                    //当前匹配上的这两个用户的状态设置成为PLAYING
                    wg->pm_->SetUserStatus(player_one, PLAYING);
                    wg->pm_->SetUserStatus(player_two, PLAYING);

                    wg->pm_->SetRoomId(player_one, room_id);
                    wg->pm_->SetRoomId(player_two, room_id);

                    /*
                     * 给用户分配黑棋还是白棋
                     * */
                    wg->pm_->SetUserChessName(player_one, "黑棋");//黑棋先走
                    wg->pm_->SetUserChessName(player_two, "白棋");

                    cout << "player_one: " << player_one << ", player_two:" << player_two << ", room_id: "<< room_id <<  endl;
                }

                wg->MatchPoolClear();
                pthread_mutex_unlock(&wg->vec_lock_);

                if(last_id > 0)
                {
                    wg->PushPlayer2MatchPool(last_id);
                }
            }
            return NULL;
        }

        void MatchPoolClear()
        {
            match_pool_.clear();
            match_pool_num_ = 0;
        }
        //将json序列化为string
        string Serializa(Json::Value& v)
        {
            Json::FastWriter w;
            return w.write(v);
        }

        int PushPlayer2MatchPool(int user_id)
        {
            //1.设置用户的状态为MATCHING状态
            pm_->SetUserStatus(user_id, MATCHING);
            //2.放到匹配池当中
            pthread_mutex_lock(&vec_lock_);
            match_pool_.push_back(user_id);
            match_pool_num_++;
            printf("match_pool_num_: %d\n", match_pool_num_);
            pthread_mutex_unlock(&vec_lock_);


            pthread_cond_broadcast(&vec_cond_);
            return 0;
        }



    private:
       RoomManager* rm_;

       Server http_svr_; 

       DataBaseSvr* db_svr_;

       AllSessionInfo* all_sess_;

       PlayerManager* pm_;


       //匹配池：vector， 需要匹配之后开始游戏的用户， 匹配线程就是通过该匹配池进行匹配
       vector<int> match_pool_;
       int match_pool_num_;
       pthread_mutex_t vec_lock_;
       pthread_cond_t vec_cond_;
};
